#pragma once

#include "MColor.h"

enum _BlendType
{
	BT_COLOR ,
	BT_ALPHA
};
typedef enum _BlendType BlendType;


enum _BlendOperation
{
	BO_REPLACE ,
    BO_ADD ,
	BO_MODULATE ,
	BO_ALPHA_BLEND
};
typedef enum _BlendOperation BlendOperation;


enum _BlendOperationEx
{
    BOX_SOURCE1 ,
	BOX_SOURCE2 ,
	BOX_MODULATE ,
	BOX_MODULATE_X2 ,
	BOX_MODULATE_X4 ,
	BOX_ADD ,
	BOX_ADD_SIGNED ,
	BOX_ADD_SMOOTH ,
	BOX_SUBTRACT ,
	BOX_BLEND_DIFFUSE_ALPHA ,
	BOX_BLEND_TEXTURE_ALPHA ,
	BOX_BLEND_CURRENT_ALPHA ,
	BOX_BLEND_MANUAL ,
	BOX_DOTPRODUCT
};
typedef enum _BlendOperationEx BlendOperationEx;


enum _BlendSource
{
	BS_CURRENT ,
	BS_TEXTURE ,
	BS_DIFFUSE ,
	BS_SPECULAR ,
	BS_MANUAL
};
typedef enum _BlendSource BlendSource;


enum _SceneBlendType
{
	SBT_TRANSPARENT_ALPHA ,
    SBT_TRANSPARENT_COLOR ,
	SBT_ADD ,
	SBT_MODULATE ,
	SBT_REPLACE
};
typedef enum _SceneBlendType SceneBlendType;


enum _SceneBlendFactor
{
	SBF_ONE ,
	SBF_ZERO ,
	SBF_DEST_COLOR ,
	SBF_SOURCE_COLOR ,
	SBF_ONE_MINUS_DEST_COLOR ,
	SBF_ONE_MINUS_SOURCE_COLOR ,
	SBF_DEST_ALPHA ,
	SBF_SOURCE_ALPHA ,
	SBF_ONE_MINUS_DEST_ALPHA ,
	SBF_ONE_MINUS_SOURCE_ALPHA
};
typedef enum _SceneBlendFactor SceneBlendFactor;


/*
 *	@brief
 *  @date  25/9/2011 
 */

class CMBlendMode
{
	bool operator==( const CMBlendMode& rhs ) const
	{
		if ( m_eType != rhs.m_eType )
		{
			return false;
		}

		if ( m_eType == BT_COLOR )
		{

			if ( m_eOperation == rhs.m_eOperation && m_eSource1 == rhs.m_eSource1 && m_eSource2 == rhs.m_eSource2 && m_ColorArg1 == rhs.m_ColorArg1 && m_ColorArg2 == rhs.m_ColorArg2 && m_fFactor == rhs.m_fFactor )
			{	return true;
			}
		}
		else if ( m_eType == BT_ALPHA )
		{
			if ( m_eOperation == rhs.m_eOperation && m_eSource1 == rhs.m_eSource1 && m_eSource2 == rhs.m_eSource2 && m_fAlphaArg1 == rhs.m_fAlphaArg1 && m_fAlphaArg2 == rhs.m_fAlphaArg2 && m_fFactor == rhs.m_fFactor )
			{	return true;
			}
		}
		return false;
	}

	bool operator!=( const CMBlendMode& rhs ) const
	{
		return !( *this == rhs );
	}

	//
	// attribute 
	//

public:

	// The type of blending (color or alpha)
	BlendType m_eType;
	// The operation to be applied
	BlendOperationEx m_eOperation;
	// The first source of color/alpha
	BlendSource m_eSource1;
	// The second source of color/alpha
	BlendSource m_eSource2;

	// Manual color value for manual source1
	CMColor m_ColorArg1;
	// Manual color value for manual source2
	CMColor m_ColorArg2;
	// Manual alpha value for manual source1
	float m_fAlphaArg1;
	// Manual color value for manual source1
	float m_fAlphaArg2;
	// Manual blending factor
	float m_fFactor;
};
